<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script>
    var lockReconnect = false;
    var socket = null;
    var wsUrl = "ws://localhost:8080/hello";

    createWebSocket(wsUrl);

    function createWebSocket(url){
        try {
    // 判断当前浏览器是否支持websocket
            if(window.WebSocket || 'WebSocket' in window){
                socket = new WebSocket(url);
            }
            initEventHandle();
        } catch (e) {
            reconnect(url);
            console.log(e);
        }
    }

    function initEventHandle(){
        socket.onclose= (e)=>{
            displayConnectStatus('连接关闭');
        };
        socket.onerror = (e)=>{
            displayConnectStatus('连接出错');
        };
        socket.onopen = (e)=>{
            // 如果获取到消息,心跳检测重置
            // 拿到任何消息都说明当前连接是正常的
            heartbeatCheck.reset().start();
            displayConnectStatus('连接打开,检测心跳');
        }
        socket.onmessage = (e)=>{
            //heartbeatCheck.reset().start();
            // 服务端返回消息
            displayConnectStatus(e.data);
        }
    }

    function displayConnectStatus(msg){
        var respText = document.getElementById('responseText');
        respText.value = respText.value + ' ' + msg;
    }

    // 发送消息到服务器
    function send(message){
    // 判断socket是否创建好
        if(!window.socket){
            console.log("本地socket不存在, 连接无法开启");
            return;
        }
        if(socket.readyState == WebSocket.OPEN){
            socket.send(message);
        }else{
            console.log("连接打开失败,请检查网络或者防火墙!");
        }
    }

    window.onbeforeunload = ()=>{
        socket.close();
    }

    function reconnect(url) {
        if (lockReconnect) return;
        lockReconnect = true;
        // 没连接上,会一直重连,设置延迟10s,避免频繁连接
        setTimeout(()=>{
            createWebSocket(url);
            lockReconnect = false;
        }, 10000);
    }

    var heartbeatCheck = {
        timeout: 10000,
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function(){
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function(){
            var self = this;
            this.timeoutObj = setTimeout(()=>{
                // 这里发送一个心跳,后端收到后,返回一个心跳消息
                // onmessage拿到返回的心跳说明连接正常
                socket.send('ping');
                // 如果超过一定时间还没重置, 说明后端连接已经断开了
                self.serverTimeoutObj = setTimeout(()=>{
                    // 如果onclose会执行reconnect, 这里执行socket.close()就行了
                    socket.close();
                }, self.timeout);
            }, this.timeout);
        }
    };
</script>
<body>
<form onsubmit="return false">
    <textarea name="message" style="height:300px; width:300px"></textarea>
    <input type="button" value="发送消息" onclick="send(this.form.message.value)">
    <textarea id="responseText" style="height:300px; width:300px"></textarea>
    <input type="button" value="清空内容" onclick="document.getElementById('responseText').value=''">
</form>
</body>
</html>